package rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import interfaz.TDACasaCentral;
import srv.*;
import beans.*;
import entities.*;

public class CasaCentral extends UnicastRemoteObject implements TDACasaCentral
{
	private static final long serialVersionUID = 1L;
	
	private double ganancia;
	private int idCasaCentral;
	private Date fechaInicioActividades;
	
	public CasaCentral() throws RemoteException 
	{
		super();
	}
	
	/**
	 * Modificar Ganancia
	 * @param g
	 * @throws RemoteException
	 */
	
	public void modificarGanancia( int g) throws RemoteException
	{
		this.ganancia = g;
	}
	
	/**
	 * Alta de un Rodamiento
	 * @param codSKF
	 * @param proveedor
	 * @param caracteristica
	 * @param medida
	 * @param tipo
	 * @param marca
	 * @param origen
	 * @param cantStock
	 * @param precioStock
	 * @throws RemoteException
	 */
	
	/*public void altaRodamiento( String codSKF,
								ProveedorBean proveedor,
								String caracteristica,
								int medida,
								String tipo,
								String marca,
								String origen,
								int cantStock,
								double precioStock ) throws RemoteException */
	public boolean altaRodamiento( RodamientoBean rodamiento )
	{
		/*
		RodamientoBean rodamientoBean = new RodamientoBean();
		rodamientoBean.setCodigoSkf(codSKF);
		rodamientoBean.setProveedor(proveedor);
		rodamientoBean.setCaracteristica(caracteristica);
		rodamientoBean.setMedida( medida );
		rodamientoBean.setTipo(tipo);
		rodamientoBean.setOrigen(origen);
		rodamientoBean.setMarca(marca);
		rodamientoBean.setCantStock(cantStock);
		rodamientoBean.setPrecioStock(precioStock);
		*/
		RodamientoEntity nuevoRodamiento = RodamientoSRV.getInstancia().pasadoDesdeBean(rodamiento);
		RodamientoSRV.getInstancia().grabarRodamiento(nuevoRodamiento);
		
		return true; //ToDo: ver como validar si se grabo o no
	}
	
	/**
	 * Baja de un Rodamiento
	 * @param rodamiento
	 * @throws RemoteException
	 */
	
	public boolean bajaRodamiento( RodamientoBean rodamientoBean ) throws RemoteException
	{	
		RodamientoEntity rodamiento =  RodamientoSRV.getInstancia().pasadoDesdeBean(rodamientoBean);
		RodamientoSRV.getInstancia().eliminarRodamiento(rodamiento);
		
		return true; //ToDo: ver como validar si se grabo o no
	}
	
	/**
	 * Modificar Rodamiento
	 * @param rodamiento
	 * @throws RemoteException
	 */
	
	public boolean modificarRodamiento( RodamientoBean rodamientoBean ) throws RemoteException
	{
		RodamientoEntity rodamiento = RodamientoSRV.getInstancia().pasadoDesdeBean(rodamientoBean);
		RodamientoSRV.getInstancia().modificarRodamiento( rodamiento );
		
		return true; //ToDo: ver como validar si se grabo o no
	}
	
	/**
	 * Consultar Stock de Rodamiento
	 * 
	 * Dado un CodigoSKF, devuelve la cantidad de stock del mismo.
	 * @param codSKF
	 * @return
	 * @throws RemoteException
	 */
	
	public int consultarStockRodamiento( String codSKF ) throws RemoteException
	{
		int stock = 0;
		stock = RodamientoSRV.getInstancia().obtenerStockRodamiento(codSKF);
		
		return stock;
	}
	
	/**
	 * Alta de Proveedor 
	 * @param proveedor
	 * @throws RemoteException
	 */
	public boolean altaProveedor( ProveedorBean proveedorBean ) throws RemoteException
	{	
		ProveedorEntity proveedor = ProveedorSRV.getInstancia().pasadoDesdeBean(proveedorBean);
		ProveedorSRV.getInstancia().grabarProveedor( proveedor);
		
		return true; //Falta validacion
	}
	
	/**
	 * Baja de un proveedor
	 * @param proveedor
	 * @throws RemoteException
	 */
	
	public boolean bajaProveedor( ProveedorBean proveedorBean ) throws RemoteException
	{	
		ProveedorEntity proveedor = ProveedorSRV.getInstancia().pasadoDesdeBean(proveedorBean);
		ProveedorSRV.getInstancia().eliminarProveedor( proveedor );
		
		return true; //Falta validacion
	}
	
	/**
	 * Modificacion de un proveedor
	 * @param proveedor
	 * @throws RemoteException
	 */
	
	public boolean modificarProveedor( ProveedorBean proveedorBean ) throws RemoteException
	{	
		ProveedorEntity proveedor = ProveedorSRV.getInstancia().pasadoDesdeBean(proveedorBean);
		ProveedorSRV.getInstancia().modificarProveedor( proveedor );
		
		return true; //falta validacion
	}
	
	/**
	 * Emitir Orden De Compra
	 * 
	 * Dada una solicitud de compra, emite la orden de compra.
	 * @param solComp
	 * @return
	 * @throws RemoteException
	 */
	public OrdenCompraBean emitirOrdenDeCompra( SolicitudCompraBean solicitudCompraBean ) throws RemoteException
	{	
		List<ItemSolicitudCompraBean> detalleDeCompra = solicitudCompraBean.getItems();	
		ProveedorBean proveedor = solicitudCompraBean.getProveedor();
		CotizacionBean solicitudCotizacion = solicitudCompraBean.getCotizacion();
		
		List<ItemCotizacionBean> detalleCotizacion = solicitudCotizacion.getItems();
		List<OrdenCompraBean> ordenesCompra = new ArrayList<OrdenCompraBean>();
						
		OrdenCompraBean oc = new OrdenCompraBean();
			
		List<ItemOrdenCompraBean> listaOrdenCompra = new ArrayList<ItemOrdenCompraBean>();
			
		for (ItemSolicitudCompraBean item : detalleDeCompra) 
		{
			if(solicitudCompraBean.getProveedor().getId() == proveedor.getId())
			{
				ItemOrdenCompraBean itemOC = new ItemOrdenCompraBean();
				itemOC.setCantidad(item.getCantidad());
				itemOC.setRodamiento(item.getRodamiento());
				itemOC.setListaDePrecios(item.getListaDePrecios());
				itemOC.setProveedor( proveedor );
					
					for(ItemCotizacionBean itemSolCot:detalleCotizacion)
					{
						if(itemSolCot.getRodamiento().getCodigoSkf().equalsIgnoreCase(item.getRodamiento().getCodigoSkf()))
						{	
							itemOC.setPrecio(itemSolCot.getPrecioCotizacion());	
						}
					}							
					listaOrdenCompra.add(itemOC);
				}				
			}
			
			oc.setItems(listaOrdenCompra);
			ordenesCompra.add(oc);
			
			OrdenCompraEntity ordenCompra = OrdenCompraSRV.getInstancia().pasadoDesdeBean(oc);
			int ordenId = OrdenCompraSRV.getInstancia().grabarOrdenCompra(ordenCompra); //ToDo: hacer que este metodo devuelva un ID...
			
			oc.setId(ordenId);
		
		return oc;
	}
		
	/**
	 * Servicio Comparativa De precios
	 * 
	 * A partir de un pedido de Venta (Solicitud de Rodamiento), calcula el mejor precio
	 * y devuelve una cotizacion
	 * 
	 * @param idPedidoVenta
	 * @return
	 * @throws RemoteException
	 */
	
	public CotizacionBean servicioComparativaDePrecios (int idPedidoVenta) throws RemoteException 
	{
		//la cotizacion que se retorna	
		CotizacionBean solicitudCotizacion = new CotizacionBean(); 
		
		//Listas de Precios Vigentes
		List<ListaPreciosEntity> listasPreciosVigentes = ListaPreciosSRV.getInstancia().obtenerListasVigentes(); 
		
		//El pedido de venta a cotizar
		PedidoVentaEntity pedidoVenta = PedidoVentaSRV.getInstancia().obtenerPedidoVentaPorId(idPedidoVenta); 
		
		ClienteEntity cliente = ClienteSRV.getInstancia().obtenerClientePorCUIT(pedidoVenta.getCliente().getCuit());
		
		List<ItemCotizacionBean> listaItemsCotizacion = new ArrayList<ItemCotizacionBean>();
		
		//Se recorre los items del pedido de ventas
		for(ItemPedidoVentaEntity itemPV : pedidoVenta.getItems())
		{   			
			ItemCotizacionBean itemCotizacionBean = new ItemCotizacionBean();
			
			//paso la cantidad del pedido de venta a la cotizacion...
			itemCotizacionBean.setCantidad(itemPV.getCantidad()); 
		
			ItemPedidoVentaBean itemPVBean = ItemPedidoVentaSRV.getInstancia().pasadoDesdeEntity(itemPV);
			itemCotizacionBean.setRodamiento( itemPVBean.getRodamiento());	
			
			//Inicializo el Item de Cotizacion
			itemCotizacionBean.setPrecioCotizacion(0);
			itemCotizacionBean.setEstadoItem("");	
			
			//Se recorre la lista de precios
			for (ListaPreciosEntity listaPrecio : listasPreciosVigentes) 
			{    
				ProveedorEntity proveedor = new ProveedorEntity();
				
				try 
				{
					proveedor = ProveedorSRV.getInstancia().obtenerProveedorPorCUIT( listaPrecio.getProveedor().getCUIT() );
				} 
				catch (Exception e) 
				{
					e.printStackTrace();
				}
				
				// Seteo el proveedor
				listaPrecio.setProveedor(proveedor);
				
				// Se recorre los items de la lista de precios
				for( ItemListaPreciosEntity itemListaPrecios : listaPrecio.getItems() )
				{ 
					RodamientoEntity rodamiento = RodamientoSRV.getInstancia().obtenerRodamientoPorCodigoSKF( itemListaPrecios.getRodamiento().getCodigoSkf() ); //OBTENGO UN ITEM DE LA LISTA DE PRECIOS
					
					//Calculo el precio de descuento de cada item
					float precioDescuento = itemListaPrecios.getPrecio() - ( itemListaPrecios.getPrecio() * itemListaPrecios.getDescuento() );
					
					itemListaPrecios.setRodamiento(rodamiento);					
					
					//Comparo el rodamiento
					if(itemListaPrecios.getRodamiento().getMarca().equalsIgnoreCase(itemPV.getRodamiento().getMarca())
						&& itemListaPrecios.getRodamiento().getOrigen().equalsIgnoreCase(itemPV.getRodamiento().getOrigen())
						&& itemListaPrecios.getRodamiento().getCaracteristica().equalsIgnoreCase(itemPV.getRodamiento().getCaracteristica())
						&& itemListaPrecios.getRodamiento().getMedida() == itemPV.getRodamiento().getMedida() )
					{
						//Chequeo el precio de Cotizacion
						if(itemCotizacionBean.getPrecioCotizacion() < itemListaPrecios.getPrecio() || itemCotizacionBean.getPrecioCotizacion() < precioDescuento);
						{ 
							//Seteo el item como Aprobado, ya que paso la condicion
							itemCotizacionBean.setEstadoItem("Aprobado");	
								
							if(itemListaPrecios.getPrecio() > precioDescuento )
							{
								itemCotizacionBean.setPrecioCotizacion(precioDescuento * cliente.getSucursal().getGanancia() / cliente.getDescuento());
							}
							else
							{
								itemCotizacionBean.setPrecioCotizacion(itemListaPrecios.getPrecio() * cliente.getSucursal().getGanancia() / cliente.getDescuento());
							}
					   	}													
					}
				}
			}
				//Agrego el item a la lista
			listaItemsCotizacion.add(itemCotizacionBean);
		}
		
		solicitudCotizacion.setItems(listaItemsCotizacion);
		PedidoVentaBean pvBean = PedidoVentaSRV.getInstancia().pasadoDesdeEntity( pedidoVenta );
		solicitudCotizacion.setCliente(pvBean .getCliente());
		solicitudCotizacion.setFechaRemisionAlCliente(new Date());
			
		Date fechaVencimiento = solicitudCotizacion.getFechaRemisionAlCliente();    
			
		Calendar cal = Calendar.getInstance(); 
		cal.setTime(fechaVencimiento);   
		cal.add(Calendar.DATE, 30); // vencimiento a los 30 dias de generado el pedido de Ventas...
		fechaVencimiento = cal.getTime();
			
		solicitudCotizacion.setFechaValidez(fechaVencimiento);
		solicitudCotizacion.setEstadoCotizacion("Pendiente");
		solicitudCotizacion.setPedidoVenta( pvBean );
			
		//Registro la cotizacion en la Base de Datos.
		CotizacionEntity solicitudCotizacionEntity = CotizacionSRV.getInstancia().pasadoDesdeBean(solicitudCotizacion ); 
		CotizacionSRV.getInstancia().registrarCotizacion( solicitudCotizacionEntity );
			
			//actualizo el estado del pedido de Ventas
		pedidoVenta.setProcesado(true);
		PedidoVentaSRV.getInstancia().actualizarPedidoVenta( pedidoVenta ); 
			
		return solicitudCotizacion;
	}
	
	/**
	 * Emitir Solicitudes de COmpra
	 * @param items
	 * @param proveedor
	 * @return
	 * @throws RemoteException
	 */
	
	@SuppressWarnings("null")
	public List<SolicitudCompraBean> emitirSolicitudesDeCompra( List<ItemSolicitudCompraBean> items, ProveedorBean proveedor ) throws RemoteException
	{
		List<SolicitudCompraBean> solicitudes = null;
		
		SolicitudCompraBean nuevaSolicitudCompra = new SolicitudCompraBean();
		nuevaSolicitudCompra.setFecha( new Date() );
		nuevaSolicitudCompra.setItems( items );
		nuevaSolicitudCompra.setProveedor( proveedor );
		
		//grabo la solicitud de compra
		SolicitudCompraEntity nuevaSolicitudCompraEntity = SolicitudCompraSRV.getInstancia().pasadoDesdeBean( nuevaSolicitudCompra );
		SolicitudCompraSRV.getInstancia().grabarSolicitudCompra(nuevaSolicitudCompraEntity);
		
		//agrego al vector de solicitudes...
		solicitudes.add(nuevaSolicitudCompra);
		
		return solicitudes; 
	}
	
	/**
	 * Buscar Equivalentes
	 * @param r
	 * @return
	 * @throws RemoteException
	 */
	
	@SuppressWarnings("null")
	public List<RodamientoBean> buscarEquivalentes( RodamientoBean r ) throws RemoteException
	{	
		RodamientoEntity re = RodamientoSRV.getInstancia().pasadoDesdeBean(r);
		List<RodamientoEntity> equivalentesEntity = RodamientoSRV.getInstancia().buscarEquivalentes(re);
		List<RodamientoBean> equivalentes = null;
		
		for( RodamientoEntity rodamientoEntity : equivalentesEntity)
		{
			RodamientoBean equivalente = RodamientoSRV.getInstancia().pasadoDesdeEntity(rodamientoEntity);
			equivalentes.add(equivalente);
		}
		return equivalentes;
	}
	
	/**
	 * Obtener Items por marca y Origen
	 * @param it
	 * @param marca
	 * @param origen
	 * @return
	 * @throws RemoteException
	 */
	
	@SuppressWarnings("null")
	public List<ItemCotizacionBean> obtenerItemsPorMarcaYOrigen( ItemCotizacionBean it, String marca, String origen ) throws RemoteException
	{
		ItemCotizacionEntity itEntity = ItemCotizacionSRV.getInstancia().pasadoDesdeBean( it );
		List<ItemCotizacionEntity> itemsEntity = ItemCotizacionSRV.getInstancia().obtenerItemsPorMarcaYOrigen(itEntity, marca, origen);
		
		List<ItemCotizacionBean> items = null;
		
		for( ItemCotizacionEntity itemEntity : itemsEntity )
		{
			ItemCotizacionBean itemBean = new ItemCotizacionBean();
			itemBean = ItemCotizacionSRV.getInstancia().pasadoDesdeEntity(itemEntity);
			items.add( itemBean );
		}
		
		return items;
	}
	
	/**
	 * Modificar Precio de La Cotizacion
	 * @param i
	 * @param nuevoPrecio
	 * @throws RemoteException
	 */
	public void modificarPrecio( ItemCotizacionBean i, float nuevoPrecio ) throws RemoteException
	{
		i.setPrecioCotizacion( nuevoPrecio );
		ItemCotizacionEntity iEntity = ItemCotizacionSRV.getInstancia().pasadoDesdeBean( i );
		ItemCotizacionSRV.getInstancia().modificarItem(iEntity);
	}
	
	/**
	 * Hay suficiente Stock
	 * @param i
	 * @return
	 * @throws RemoteException
	 */
	
	public boolean haySuficienteStock( ItemCotizacionBean i ) throws RemoteException
	{
		ItemCotizacionEntity iEntity = ItemCotizacionSRV.getInstancia().pasadoDesdeBean( i );
		return ItemCotizacionSRV.getInstancia().haySuficienteStock( iEntity );
	}
	
	/**
	 * Generar Remito
	 * @param pv
	 * @return
	 * @throws RemoteException
	 */
	
	@SuppressWarnings("null")
	public RemitoBean generarRemito( PedidoVentaBean pv ) throws RemoteException
	{
		RemitoBean nuevoRemito = new RemitoBean();
		//vector de items del nuevo remito
		List<ItemRemitoBean> listaItemsRemito = null; 
		//cada item del remito
		ItemRemitoBean remitoItem = new ItemRemitoBean();
		//Items de la cotizacion
		List<ItemPedidoVentaBean> pvItems = pv.getItems();
		
		for( int i = 0; i < pvItems.size(); i++)
		{
			//agrego los items al remito
			remitoItem.setRodamiento( pvItems.get( i ).getRodamiento() );
			remitoItem.setCantidad( pvItems.get( i ).getCantidad() );
			remitoItem.setPrecio( pvItems.get( i ).getPrecio() );
			
			listaItemsRemito.add( remitoItem );
		}
		
		//cargo el vector de items en el remito...
		nuevoRemito.setItems( listaItemsRemito );
		
		
		RemitoEntity nuevoRemitoEntity = RemitoSRV.getInstancia().pasadoDesdeBean( nuevoRemito );
		RemitoSRV.getInstancia().grabarRemito( nuevoRemitoEntity );
		
		return nuevoRemito;
	}
	
	/**
	 * Metodo que se encarga de guardar Lista de Precios
	 * @param listaPrecios
	 * @return
	 * @throws RemoteException
	 */
	public boolean guardarListaPrecios (ListaPreciosBean listaPrecios )throws RemoteException
	{	
		if(listaPrecios.getProveedor() != null)
		{
			ListaPreciosEntity listaPreciosEntity = ListaPreciosSRV.getInstancia().pasadoDesdeBean(listaPrecios);
			ListaPreciosSRV.getInstancia().guardarListaPrecios(listaPreciosEntity);
			return true;
		}
		return false;
	}
	
	/**
	 * Obtener Lista de Precios
	 * @param proveedor
	 * @return
	 */
	
	public ListaPreciosBean obtenerListaPrecios( ProveedorBean proveedor )
	{
		ProveedorEntity proveedorEntity = ProveedorSRV.getInstancia().pasadoDesdeBean(proveedor);
		ListaPreciosEntity listaPreciosEntity = ListaPreciosSRV.getInstancia().obtenerListaPrecios( proveedorEntity );
		
		ListaPreciosBean listaPrecios = ListaPreciosSRV.getInstancia().pasadoDesdeEntity(listaPreciosEntity);
		
		return listaPrecios;
	}

	/**
	 * @return the ganancia
	 */
	public double getGanancia() throws RemoteException
	{
		return ganancia;
	}

	/**
	 * @param ganancia the ganancia to set
	 */
	public void setGanancia(double ganancia) throws RemoteException
	{
		this.ganancia = ganancia;
	}

	/**
	 * @return the idCasaCentral
	 */
	public int getIdCasaCentral() throws RemoteException
	{
		return idCasaCentral;
	}

	/**
	 * @param idCasaCentral the idCasaCentral to set
	 */
	public void setIdCasaCentral(int idCasaCentral) throws RemoteException
	{
		this.idCasaCentral = idCasaCentral;
	}

	/**
	 * @return the fechaInicioActividades
	 */
	public Date getFechaInicioActividades() throws RemoteException
	{
		return fechaInicioActividades;
	}

	/**
	 * @param fechaInicioActividades the fechaInicioActividades to set
	 */
	public void setFechaInicioActividades(Date fechaInicioActividades) throws RemoteException
	{
		this.fechaInicioActividades = fechaInicioActividades;
	}
	
	public UsuarioBean loginUsuario(UsuarioBean usuarioLogin ) throws RemoteException 
	{
		System.out.println("Usuario " + usuarioLogin.getUsername() + " Logeuandose.");
		UsuarioBean usuario = UsuarioSRV.getinstancia().loginUsuario(usuarioLogin);
		
		if( usuario != null )
		{
			UsuarioBean usuarioBean = new UsuarioBean();
			usuarioBean.setId(usuario.getId());
			usuarioBean.setNombre(usuario.getNombre());
			usuarioBean.setPassword(usuario.getPassword());
			usuarioBean.setUsername(usuario.getUsername());
			usuarioBean.setPerfil(usuario.getPerfil());
			return usuarioBean;
		}
		else
		{
			return null;
		}
	}
	
	public RodamientoBean buscarRodamiento (String codigoSKF)
	{
		RodamientoBean rodamiento = new RodamientoBean();
		
		RodamientoEntity rodamientoEntity = RodamientoSRV.getInstancia().obtenerRodamientoPorCodigoSKF(codigoSKF);
		
		rodamiento = RodamientoSRV.getInstancia().pasadoDesdeEntity(rodamientoEntity);
		
		return rodamiento;
	}
	
	public List<PedidoVentaBean> obtenerPedidosVentaPorCliente(String cuit) throws RemoteException 
	{	
		List<PedidoVentaEntity> listaPvEntity = PedidoVentaSRV.getInstancia().obtenerPedidosVentaPorCliente(cuit);
		List<PedidoVentaBean> listaPvBean = new ArrayList<PedidoVentaBean>();
		
		for(PedidoVentaEntity pv:listaPvEntity)
		{
			PedidoVentaBean pvBean = PedidoVentaSRV.getInstancia().pasadoDesdeEntity( pv );
			listaPvBean.add( pvBean);
		}		
		return listaPvBean;
	}

	@Override
	public boolean modificarODV(OficinaVentaBean odv) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<ClienteBean> obtenerClientesPorCriterio(String razonSocial, String cuit) throws RemoteException //falta 
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ClienteBean obtenerClientePorCuit(String cuit) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ProveedorBean obtenerProveedorPorCuit(String cuit) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public RodamientoBean obtenerRodamientoPorCodigo(String codigo) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean cargarListaPrecios(ListaPreciosBean lista) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean generarCotizacion(CotizacionBean cot) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<CotizacionBean> obtenerCotizacionesPorCliente(String cuit) throws RemoteException //falta 
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public SolicitudCompraBean generarSolicitudCompra(CotizacionBean cot) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public FacturaBean generarFactura(CotizacionBean cot) throws RemoteException //falta
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<OrdenCompraBean> generarOrdenesCompra( SolicitudCompraBean solComp) throws RemoteException //falta 
	{
		// TODO Auto-generated method stub
		return null;
	}
}